﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MDF.Logger.Managements;


using MDF.Cacher.Managements;
using TGVR.DataHelper.BussinessLogic.BookingSystem;
using TGVR.DataHelper.BussinessObject.BookingSystem;

namespace TGVR_Boot
{
    public class AbacusBoot : IBoot
    {
        List<BK_Ticket> IBoot.Search(string _strStationFrom, string _strStationTo, DateTime _dtDateFrom, DateTime? _dtDateTo, int _iAdut, int _iChild, int _iBaby, bool _isInter, int _iUserID)
        {

            #region Cache management
            string strKeyword = "AbacusBoot" + _strStationFrom + _strStationTo + _dtDateFrom.ToString("MMddyyyyhhmm") +
                (_dtDateTo.HasValue ? _dtDateTo.Value.ToString("MMddyyyyhhmm") : "") + _iAdut.ToString() + _iChild.ToString() + _iBaby.ToString() + "_User" + _iUserID;
            //m_log.Info("Search: " + strKeyword);
            var cacheResult = CacheManager.GetInstance().Get(strKeyword);
            if (cacheResult != null)
            {
                //m_log.Info("Get from cache");
                return (List<BK_Ticket>)cacheResult;
            }
            #endregion

            #region Find tickets
            List<BK_Ticket> lstResult = new List<BK_Ticket>();
            try
            {

                #region Seach tickets
                MDF.Requesting.Requester rq = new MDF.Requesting.Requester();
                string strSearchLink = "https://abacuswebstart.abacus.com.sg/hnh/flight-search-process.aspx";
                string strData = string.Format("from1=Ho+Chi+Minh+%28{0}%29&to1=Bangkok+Suvarnabhumi+%28{1}%29&departureDate1={2}+00%3A01%3A00&from2=Bangkok+Suvarnabhumi+%28{1}%29&to2=Ho+Chi+Minh+%28{0}%29&departureDate2={3}+00%3A01%3A00&tripType={4}&adult={5}&child={6}&infant={7}&student=0&seaman=0&seniorCitizen=0&labour=0&class=Y&flightType=2&prefAirline=",
                    _strStationFrom,//0
                    _strStationTo,//1
                    _dtDateFrom.ToString("yyyy-MM-dd"),//2
                    _dtDateTo.HasValue ? _dtDateTo.Value.ToString("yyyy-MM-dd") : "",//3
                    _dtDateTo.HasValue ? "2" : "1",//4
                    _iAdut,//5
                    _iChild,//6
                    _iBaby//7
                    );
                var res = rq.PostData(strSearchLink, strData);
                string strHTML = rq.GetHtmlFromResponse(res);

                if (res == null || string.IsNullOrEmpty(strHTML))
                {
                    LogManager.GetInstance().Error("Abacus: Can not send request find ticket");
                    return lstResult;
                }

                string strLinkResult = "https://abacuswebstart.abacus.com.sg/hnh/ajax-flight.aspx";
                string strDataResult = "action_type=SEARCH&page=0&pagesize=100";
                var resResult = rq.PostData(strLinkResult, strDataResult);
                string strHTMLResult = rq.GetHtmlFromResponse(resResult);

                if (resResult == null || string.IsNullOrEmpty(strHTMLResult))
                {
                    LogManager.GetInstance().Error("Abacus: Can not send request get ticket");
                    return lstResult;
                }

                int iStart = strHTMLResult.IndexOf("<![CDATA[") + 9;
                int iEnd = strHTMLResult.IndexOf("]]>");

                strHTMLResult = strHTMLResult.Substring(iStart, iEnd - iStart);

                #endregion

                #region Get Tickets

                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(strHTMLResult);
                var tickets = doc.DocumentNode.SelectNodes("//*[@class=\"flightResult\"]/table");
                if (tickets == null || tickets.Count == 0)
                {
                    LogManager.GetInstance().Error("Abacus: can not find ticket");
                    return lstResult;
                }

                var lstFirm = TK_FirmBUS.Current.GetAll();
                var iDollar = Int32.Parse(SettingBUS.Current.GetSetting(_iUserID,"DollarAbacus").Value);
                var iFee = Int32.Parse(SettingBUS.Current.GetSetting(_iUserID, "FeeAbacusInter").Value);
                foreach (var item in tickets)
                {

                    HtmlAgilityPack.HtmlDocument docTicket = new HtmlAgilityPack.HtmlDocument();
                    docTicket.LoadHtml(item.InnerHtml);
                    var ticketFirms = docTicket.DocumentNode.SelectNodes("/tr[1]/td[1]/table/tr[2]/td[2]/table[1]");
                    if (ticketFirms == null || ticketFirms.Count == 0)
                    {
                        //tim ve 1,2 chiều
                        LogManager.GetInstance().Error("Abacus: can not find ticket with firms");
                        return lstResult;
                    }
                    string strPrice = docTicket.DocumentNode.SelectNodes("//*[@class='flightResultPricePn']/span[3]")[0].InnerText;
                    int iPrice = 0;
                    if (!Int32.TryParse(strPrice, out iPrice))
                    {
                        LogManager.GetInstance().Error("Abacus canot get price!");
                        continue;
                    }
                    for (int i = 0; i < ticketFirms.Count; i++)
                    {
                        #region Create ticket type way
                        BK_Ticket ticket = new BK_Ticket();
                        ticket.PriceBefore = iPrice* iDollar;
                        ticket.Price = (iPrice + iFee) * iDollar;
                        if (i == 0)
                            ticket.TypeWay = "Out";
                        if (i == 1)
                            ticket.TypeWay = "In";
                        #endregion

                        #region Get ticket information
                        HtmlAgilityPack.HtmlDocument docDetail = new HtmlAgilityPack.HtmlDocument();
                        docDetail.LoadHtml(ticketFirms[i].InnerHtml);
                        //Get flightNo
                        var strImgFlight = docTicket.DocumentNode.SelectNodes(string.Format("/tr[1]/td[1]/table[{0}]/tr[2]/td[1]/div[1]/img[1]", i + 1));
                        if (strImgFlight != null)
                        {
                            string flightNo = strImgFlight[0].Attributes["alt"].Value;
                            var firm = lstFirm.Where(m => m.Name.ToLower().IndexOf(flightNo.ToLower()) > -1).SingleOrDefault();
                            ticket.Image = string.Format("http://thegioivere.net/content/images/logo/{0}.png", flightNo);
                            if (firm == null)
                            {
                                ticket.Image = strImgFlight[0].Attributes["src"].Value;
                                //DataHelper.TK_Firm objFirm = new DataHelper.TK_Firm();
                                //objFirm.Adult = 100;
                                //objFirm.Baby = 100;
                                //objFirm.Child = 100;
                                //objFirm.Fullname = flightNo;
                                //objFirm.HoldingTime = 24;
                                //objFirm.Image = ticket.Image;

                                LogManager.GetInstance().Warn("Abacus don't have icon for " + flightNo);
                            }
                        }
                        //Get time
                        string from = docDetail.DocumentNode.SelectNodes("//tr//td//b")[0].InnerText;
                        string to = docDetail.DocumentNode.SelectNodes("//tr//td//b")[1].InnerText;

                        //Get depart station
                        string[] arrTicket = from.Split(' ');
                        if (arrTicket[0].ToLower() == (i == 0 ? _strStationFrom.ToLower() : _strStationTo.ToLower()))
                            ticket.FromCity = (i == 0 ? _strStationFrom : _strStationTo);
                        else
                            LogManager.GetInstance().Error("Abacus: The depart station is not right!");
                        try
                        {
                            int iHour = Int32.Parse(arrTicket[1].Split('.')[0]);
                            int iMinute = Int32.Parse(arrTicket[1].Split('.')[1]);
                            if (i == 0)
                                ticket.StartDate = new DateTime(_dtDateFrom.Year, _dtDateFrom.Month, _dtDateFrom.Day, iHour, iMinute, 0);
                            else
                                ticket.StartDate = new DateTime(_dtDateTo.Value.Year, _dtDateTo.Value.Month, _dtDateTo.Value.Day, iHour, iMinute, 0);
                        }
                        catch
                        {
                            LogManager.GetInstance().Error("Abacus: Cant not find time of flight");
                        }
                        //end

                        //Get depart station
                        arrTicket = to.Split(' ');
                        if (arrTicket[0].ToLower() == (i == 0 ? _strStationTo.ToLower() : _strStationFrom.ToLower()))
                            ticket.ToCity = (i == 0 ? _strStationTo : _strStationFrom);
                        else
                            LogManager.GetInstance().Error("Abacus: The depart station is not right!");
                        try
                        {
                            int iHour = Int32.Parse(arrTicket[1].Split('.')[0]);
                            int iMinute = Int32.Parse(arrTicket[1].Split('.')[1]);
                            if (i == 0)
                                ticket.EndDate = new DateTime(_dtDateFrom.Year, _dtDateFrom.Month, _dtDateFrom.Day, iHour, iMinute, 0);
                            else
                                ticket.EndDate = new DateTime(_dtDateTo.Value.Year, _dtDateTo.Value.Month, _dtDateTo.Value.Day, iHour, iMinute, 0);
                        }
                        catch
                        {
                            LogManager.GetInstance().Error("Abacus: Cant not find time of flight");
                        }
                        //end
                        ticket.LastUpdate = DateTime.Now;
                        lstResult.Add(ticket);
                        #endregion
                    }
                }

                #endregion

            }
            catch (Exception ex)
            {
                LogManager.GetInstance().Error("AbacusBoot have error!", ex);
            }
            if (lstResult != null && lstResult.Count > 0)
            {
                CacheManager.GetInstance().Add(strKeyword, lstResult.ToList());
            }
            return lstResult;
            #endregion

        }

        List<BK_Ticket> IBoot.SearchCheapest(string _strStationForm, string _strStationTo, DateTime _dtDateFrom, DateTime? _dtDataTo, int _iAdut, int _iChild, int _iBaby, int _iUserID)
        {
            throw new NotImplementedException();
        }

        int IBoot.MakeBooking(BK_Booking booking, BK_Passenger[] passenges, BK_Ticket tkDepart, BK_Ticket tkReturn, int _iUserID)
        {
            throw new NotImplementedException();
        }

        string IBoot.GetCode()
        {
            throw new NotImplementedException();
        }

        int IBoot.GetTotal()
        {
            throw new NotImplementedException();
        }

        private DateTime HoldToDate;
        public DateTime GetHoldToDate()
        {
            return HoldToDate;
        }
    }
}
